package cn.mumzone.pos.presenter;

import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sunmi.payment.PaymentService;

import java.util.HashMap;

import cn.mumzone.basic.mvp.AbsPresenter;
import cn.mumzone.basic.net.http.callback.ApiCallBack;
import cn.mumzone.basic.net.response.BaseResponse;
import cn.mumzone.basic.util.BigDecimalUtil;
import cn.mumzone.basic.util.DeviceIdUtils;
import cn.mumzone.basic.util.MoneyFormatUtil;
import cn.mumzone.basic.util.PatternUtils;
import cn.mumzone.basic.util.RxBus;
import cn.mumzone.basic.util.StringUtils;
import cn.mumzone.basic.util.log.Elog;
import cn.mumzone.pos.BuildConfig;
import cn.mumzone.pos.event.DepositGoodsNumEvent;
import cn.mumzone.pos.event.NetConnectedEvent;
import cn.mumzone.pos.event.RedeemSuccessEvent;
import cn.mumzone.pos.event.TimeCardNumEvent;
import cn.mumzone.pos.model.BillDetailEntity;
import cn.mumzone.pos.model.MemberEntity;
import cn.mumzone.pos.model.RechargeDetailEntity;
import cn.mumzone.pos.model.SettleResultEntity;
import cn.mumzone.pos.model.SunMiPayRequestEntity;
import cn.mumzone.pos.model.source.AppRepository;
import cn.mumzone.pos.model.source.BillsRepository;
import cn.mumzone.pos.model.source.MemberRepository;
import cn.mumzone.pos.model.source.SettleRepository;
import cn.mumzone.pos.presenter.contract.MemberDetailContract;
import cn.mumzone.pos.util.AppUtil;
import cn.mumzone.pos.util.BillUtil;
import cn.mumzone.pos.util.PayCountDownTimer;
import rx.Subscription;
import rx.functions.Action1;

import static cn.mumzone.pos.presenter.SettleAccountPresenter.CODE_BANK_TIME_OUT;
import static cn.mumzone.pos.presenter.SettleAccountPresenter.CODE_SUN_MI_NET_ERROR;
import static cn.mumzone.pos.presenter.SettleAccountPresenter.CODE_SUN_MI_QUERY_TIME_OUT;

/**
 * Created By Dlx
 * on 2019/7/3
 */
public class MemberDetailPresenter extends AbsPresenter<MemberDetailContract.View, MemberRepository> implements MemberDetailContract.Presenter {

    SettleRepository settleRepository;
    BillsRepository billsRepository;
    private String memberId;
    private String phone;
    private HashMap<String, String> payTypeMap = new HashMap<>();
    private boolean isExecutedScan = false;

    private String saleId;

    private PayCountDownTimer payCountDownTimer;
    private static final int COUNT_DOWN_TIME = 125;
    private boolean isFacePay = false;

    private boolean isFirstSunMiTimeOut = false;
    private boolean isSunMiNetError = false;
    private String orderId = "";
    private boolean isRecharge = false;


    @Override
    protected void initOtherRepository() {
        super.initOtherRepository();
        settleRepository = new SettleRepository();
        billsRepository = new BillsRepository();
    }

    public void initVariable(String memberId, String phone) {
        this.memberId = memberId;
        this.phone = phone;

        payCountDownTimer = new PayCountDownTimer(COUNT_DOWN_TIME * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                super.onTick(millisUntilFinished);
                Elog.e("TAG----", millisUntilFinished);
                long time = millisUntilFinished / 1000;
                mView.showTimeChanged(time);
                if (time <= COUNT_DOWN_TIME - 120) {
                    if (isFirstSunMiTimeOut) {
                        querySmPayOrderInfo(false);
                        isFirstSunMiTimeOut = false;
                    }
                }
            }

            @Override
            public void onFinish() {
                super.onFinish();
                mView.showSunMiPayNetError();
                mView.showTimeChanged(COUNT_DOWN_TIME);
            }
        };

        Subscription netConnectListener = RxBus.getDefault()
                .toObservable(NetConnectedEvent.class)
                .subscribe(new Action1<NetConnectedEvent>() {
                    @Override
                    public void call(NetConnectedEvent netConnectedEvent) {
                        if (isSunMiNetError) {
                            isSunMiNetError = false;
                            querySmPayOrderInfo(true);
                        }
                    }
                });
        addSubscrebe(netConnectListener);
    }

    @Override
    public void getMemberDetail(String phone) {
        mView.showLoadingDialog();
        ApiCallBack<MemberEntity> callBack = new ApiCallBack<MemberEntity>() {
            @Override
            public void onSuccess(MemberEntity memberEntity) {
                mView.setMemberDetailData(memberEntity);
                mView.dismissLoadingDialog();
            }

            @Override
            public void onError(BaseResponse response) {
                mView.showError(response.getMsg());
                mView.dismissLoadingDialog();
            }

            @Override
            public void onNetworkError(BaseResponse response) {
                mView.showNetError();
            }
        };
        mRepo.getMemberDetailByPhone(phone, callBack);
        addSubscrebe(callBack);
    }

    @Override
    public void onEvent() {
        //当退卡、或购买次卡后  刷新次卡列表，然后标题也要对应修改
        Subscription timeCardNumEvent = RxBus.getDefault()
                .toObservable(TimeCardNumEvent.class)
                .subscribe(new Action1<TimeCardNumEvent>() {
                    @Override
                    public void call(TimeCardNumEvent timeCardNumEvent) {
                        mView.setTimesCardNum(timeCardNumEvent.getTimeCardNum());
                    }
                });
        addSubscrebe(timeCardNumEvent);


        //当领取寄存商品时，会刷新寄存商品列表，当某一商品领完了，此时要同步刷新标题数据
        Subscription depositGoodsNumEvent = RxBus.getDefault()
                .toObservable(DepositGoodsNumEvent.class)
                .subscribe(new Action1<DepositGoodsNumEvent>() {
                    @Override
                    public void call(DepositGoodsNumEvent depositGoodsNumEvent) {
                        mView.setDepositGoodsNum(depositGoodsNumEvent.getDepositGoodsNum());
                    }
                });
        addSubscrebe(depositGoodsNumEvent);
        Subscription redeemSuccessListener = RxBus.getDefault()
                .toObservable(RedeemSuccessEvent.class)
                .subscribe(new Action1<RedeemSuccessEvent>() {
                    @Override
                    public void call(RedeemSuccessEvent redeemSuccessEvent) {
                        getMemberDetail(phone);
                    }
                });
        addSubscrebe(redeemSuccessListener);
    }

    @Override
    public void settleOrderWithCash(String cashInput) {

        // 屏蔽错误格式
        String formattedMoney = MoneyFormatUtil.getFormattedMoney(cashInput, true);
        if (TextUtils.isEmpty(formattedMoney) && Double.parseDouble(cashInput) <= 0) {
            mView.showError("输入金额有误");
            return;
        }

//        // 输入金额小于待收金额时，截断
//        if (Double.parseDouble(cashInput) < Double.parseDouble(this.toPayAmount)) {
//            mView.showError("输入金额不正确，请检查后重新输入！");
//            return;
//        }

        // 更新支付方式，计算找零金额，发起支付
        updatePayTypeMap(true, BillUtil.PAY_TYPE_CASH, cashInput);
//        double cashChange = Double.parseDouble(cashInput) - Double.parseDouble(this.toPayAmount);
//        if (cashChange <= 0) {
//            if (cashChange < 0)
//                cashChange = 0;
        requestSaveOrder("", cashInput, "0", cashInput, JSON.toJSONString(payTypeMap), false);
//        } else {
//            mView.showCashChangeDialog(String.valueOf(cashChange), cashInput);
//        }

        if (Double.valueOf(BigDecimalUtil.getNumber(cashInput)) != 0) {
            mView.openDrawer();
        }
    }

    @Override
    public void executeScanCode(String scanCode, String toPayAmount) {
        if (!isExecutedScan) {
            boolean isAliPay = payTypeMap.containsKey(BillUtil.PAY_TYPE_ALI);
            if (isAliPay) {
                if (!PatternUtils.isAliPayCode(scanCode)) {
                    mView.showError("请扫描支付宝付款码");
                    isExecutedScan = false;
                    mView.resetScanCodeStatus();
                    return;
                }
            } else {
                if (!PatternUtils.isWxPayCode(scanCode)) {
                    mView.showError("请扫描微信付款码");
                    isExecutedScan = false;
                    mView.resetScanCodeStatus();
                    return;
                }
            }
            requestSaveOrder(scanCode, toPayAmount, "", "", JSON.toJSONString(payTypeMap), false);
            mView.showWaitingDialog(isAliPay);
            payCountDownTimer.reset();
            payCountDownTimer.start();
        }
        isExecutedScan = true;
        mView.resetScanCodeStatus();
    }

    @Override
    public void settleOrderWithBank(String toPayAmount) {
//        if (orderVo != null && "1".equals(orderVo.getPayCnl())) { // 0 原生 1 中金 2 商米
//        }

        // 更新支付方式，发起支付
        requestSaveOrder("", toPayAmount, "", "", JSON.toJSONString(payTypeMap), false);

    }

    /**
     * 更新 payType 值
     *
     * @param payType        支付方式
     * @param currTypeAmount 当前支付方式的待支付金额
     */
    public void updatePayTypeMap(boolean isAdd, String payType, String currTypeAmount) {
        if (isAdd) {
            payTypeMap.clear();
            payTypeMap.put(payType, currTypeAmount);
        } else {
            payTypeMap.remove(payType);
        }
    }

    @Override
    public void executeFacePay(String toPayAmount) {
        requestSaveOrder("", toPayAmount, "", "", JSON.toJSONString(payTypeMap), true);
        mView.showWaitingDialog(true);
        payCountDownTimer.reset();
        payCountDownTimer.start();
    }

    private void requestSaveOrder(final String authCode, String toPayAmount, String cashChange, String cashCollection, final String payType, final boolean isFacePay) {
        this.isFacePay = isFacePay;
        ApiCallBack<SettleResultEntity> saveOrderCallback = new ApiCallBack<SettleResultEntity>() {
            @Override
            public void onSuccess(SettleResultEntity settleResultEntity) {

                // 回调成功后标记允许扫码，并将结果返回给 View 层
                if (!StringUtils.isEmpty(settleResultEntity.getPayCode()) && "1000".equals(settleResultEntity.getPayCode())
                        && !StringUtils.isEmpty(settleResultEntity.getOrderCode())) {
                    if (!AppUtil.isAppSunMiVersion()) {
                        mView.showError("当前安装App非商米版本,请下载商米版本后重试~");
                        return;
                    }
                    if (!AppUtil.isSunMiPos()) {
                        mView.showError("非商米POS,无法使用商米支付~");
                        return;
                    }
                    payCountDownTimer.bindData(settleResultEntity.getOrderCode());
                    JSONObject jsonObject = JSON.parseObject(payType);
                    String payValue = "0";
                    for (String key : jsonObject.keySet()) {
                        payValue = (String) jsonObject.get(key);
                    }
                    double amount = BigDecimalUtil.mul(payValue, "100");//商米支付金额单位为分
                    orderId = settleResultEntity.getOrderCode();
                    requestSunMiPay(settleResultEntity.getOrderCode(), settleResultEntity.getOrderCode(), authCode, (long) amount, isFacePay);
                } else {
                    if (isExecutedScan || isFacePay) {
                        payCountDownTimer.cancel();
                        mView.showTimeChanged(COUNT_DOWN_TIME);
                    }
                    isExecutedScan = false;
                    mView.onSettleRechargeSuccess();

                    // 获取订单信息，调用打印
                    requestOrderInfo(settleResultEntity.getSaleId());
                }
            }

            @Override
            public void onError(BaseResponse response) {
                if (isExecutedScan || isFacePay) {
                    payCountDownTimer.cancel();
                    mView.showTimeChanged(COUNT_DOWN_TIME);
                }
                isExecutedScan = false;
                if (504 == response.getCode()) {
                    saleId = response.getMsg();
                    Elog.e("LJT", " 504 ---> " + response.getMsg());
                }
                mView.showRechargeSettleError(response.getCode(), response.getMsg());
            }
        };

        HashMap<String, String> settleMap = new HashMap<>();
        settleMap.put("memberCompanyId", StringUtils.get(memberId));
        settleMap.put("phone", StringUtils.get(phone));
        settleMap.put("settleType", "3");//会员余额
        settleMap.put("posCode", DeviceIdUtils.getDeviceId());
        settleMap.put("totalAmount", MoneyFormatUtil.getFormattedMoney(toPayAmount, true));
        settleMap.put("toPayAmount", MoneyFormatUtil.getFormattedMoney(toPayAmount, true));
        settleMap.put("authCode", StringUtils.get(authCode));
        settleMap.put("cashChange", StringUtils.get(cashChange));
        settleMap.put("cashCollection", StringUtils.get(cashCollection));
        settleMap.put("payType", StringUtils.get(payType));
        settleRepository.getSettleResultInfo(settleMap, saveOrderCallback);
        addSubscrebe(saveOrderCallback);

    }


    private void requestSunMiPay(String businessId, String orderId, String code, long amount, boolean isFacePay) {
        isRecharge = true;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("appType", isFacePay ? "51" : "01");//应用类型 00:银行卡应用 01:聚合扫码支付应用 02:银行卡+银联扫码支付应用 51：扫脸支付
        jsonObject.put("transType", "00");// 交易类型 00－消费  09-退款
        jsonObject.put("appId", BuildConfig.APPLICATION_ID);// 包名
        jsonObject.put("businessId", businessId);// 业务订单号
        jsonObject.put("orderId", orderId);// 支付订单号
        jsonObject.put("amount", amount);// 金额
        jsonObject.put("payCode", code);// 付款码
        JSONObject config = new JSONObject();
        config.put("processDisplay", false);//是否显示支付进行中页面
        config.put("resultDisplay", false);//是否显示交易结果页
        config.put("printTicket", false);//打印小票
        jsonObject.put("config", config);// ui设置

        Elog.e("SUNMI_PAY", "请求参数：" + jsonObject.toJSONString());
        PaymentService.getInstance().callPayment(jsonObject.toJSONString());
    }


    @Override
    public void querySmPayOrderInfo(final boolean isSilent) {
        final ApiCallBack<SettleResultEntity> callBack = new ApiCallBack<SettleResultEntity>() {
            @Override
            public void onSuccess(SettleResultEntity settleResultEntity) {

                if (isExecutedScan || isFacePay) {
                    payCountDownTimer.cancel();
                    mView.showTimeChanged(COUNT_DOWN_TIME);
                }
                isExecutedScan = false;
                isFirstSunMiTimeOut = true;
                mView.onSettleRechargeSuccess();

                // 获取订单信息，调用打印
                requestOrderInfo(settleResultEntity.getSaleId());
            }

            @Override
            public void onError(BaseResponse response) {
                if(CODE_SUN_MI_QUERY_TIME_OUT == response.getCode()){
                    querySmPayOrderInfo(true);
                    return;
                }

                if (response.getCode() != CODE_NET_ERROR) {
                    if (isExecutedScan || isFacePay) {
                        payCountDownTimer.cancel();
                        mView.showTimeChanged(COUNT_DOWN_TIME);
                    }
                    mView.dismissLoadingDialog();
                    isExecutedScan = false;
                    isFirstSunMiTimeOut = true;
                    if (CODE_BANK_TIME_OUT == response.getCode()) {
                        saleId = response.getMsg();
                        Elog.e("LJT", " 504 ---> " + response.getMsg());
                    }
                    mView.showRechargeSettleError(response.getCode(), response.getMsg());
                }
            }

            @Override
            public void onNetworkError(BaseResponse response) {
                isSunMiNetError = true;
                if(!isSilent){
                    mView.showSunMiPayNetError();
                }
            }
        };
        settleRepository.querySmPayOrderInfo(orderId, callBack);
        addSubscrebe(callBack);
    }

    /**
     * 银行卡支付超时后，清空购物车
     * 利用 errorMsg 中的 saleId 查询订单详情，调用打印
     */
    public void requestOrderInfoAfterTimeOut() {
        if (TextUtils.isEmpty(saleId)) {
            mView.showError("订单 id 为空！");
            return;
        }

        mView.onSettleRechargeSuccess();
        requestOrderInfo(saleId);

    }

    /**
     * 生成订单并支付成功后，获取订单信息，执行打印
     *
     * @param saleId 订单id
     */
    public void requestOrderInfo(String saleId) {

        ApiCallBack<RechargeDetailEntity> billDetailCallBack = new ApiCallBack<RechargeDetailEntity>() {
            @Override
            public void onSuccess(RechargeDetailEntity billDetailEntity) {
                mView.dismissLoadingDialog();
                mView.doPrintAfterSettleSuccess(billDetailEntity);
            }

            @Override
            public void onError(BaseResponse response) {
                mView.dismissLoadingDialog();
                mView.showError(response.getMsg());
            }
        };
        mView.showLoadingDialog();
        billsRepository.getRechargeBillDetail(saleId, memberId, billDetailCallBack);
        addSubscrebe(billDetailCallBack);

    }

    @Override
    public void detachView() {
        super.detachView();
        if (payCountDownTimer != null) {
            payCountDownTimer.cancel();
        }
    }

    public boolean isRecharge() {
        return isRecharge;
    }

    public void setRecharge(boolean recharge) {
        isRecharge = recharge;
    }
}
